/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2022-08-28     chenbin       the first version
 */
#include "ch32v30x.h"
#include <rtthread.h>
#include "drv_tm16xx.h"


//#define TM16XX_STB_H  rt_pin_write(KD_STB_PIN, PIN_HIGH); //STB----1
//#define TM16XX_STB_L  rt_pin_write(KD_STB_PIN, PIN_LOW);  //STB----0
//
//#define TM16XX_CLK_H  rt_pin_write(KD_CLK_PIN, PIN_HIGH); //CLK----1
//#define TM16XX_CLK_L  rt_pin_write(KD_CLK_PIN, PIN_LOW);  //CLK----0
//
//#define TM16XX_DIO_H  rt_pin_write(KD_DIO_PIN, PIN_HIGH); //DIO----1
//#define TM16XX_DIO_L  rt_pin_write(KD_DIO_PIN, PIN_LOW);  //DIO----0
//
//#define TM16XX_DIO_IN   rt_pin_read(KD_DIO_PIN)


#define TM1668_STB_H  GPIO_SetBits(GPIOD, GPIO_Pin_8) //STB----1
#define TM1668_STB_L  GPIO_ResetBits(GPIOD, GPIO_Pin_8)  //STB----0

#define TM1668_CLK_H  GPIO_SetBits(GPIOD, GPIO_Pin_9) //CLK----1
#define TM1668_CLK_L  GPIO_ResetBits(GPIOD, GPIO_Pin_9)  //CLK----0

#define TM1668_DIO_H  GPIO_SetBits(GPIOD, GPIO_Pin_10) //DIO----1
#define TM1668_DIO_L  GPIO_ResetBits(GPIOD, GPIO_Pin_10)  //DIO----0

#define TM1668_DIO_STATUS   GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_10)


void tm1668_dio_output(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void tm1668_dio_input(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void tm1668_gpio_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void tm1668_delay(int n)
{
    uint32_t temp = 0;
    //delay_us(n);
    while(n--)
    {
        temp = 1000;
        while(temp--);
    }
}

void tm1668_delay_1us(void)
{
    tm1668_delay(10);
}



#undef  TM16XX_STB_H
#undef  TM16XX_STB_L
#undef  TM16XX_CLK_H
#undef  TM16XX_CLK_L
#undef  TM16XX_DIO_H
#undef  TM16XX_DIO_L
#undef  TM16XX_DIO_STATUS
#undef  TM16XX_DIO_OUTPUT
#undef  TM16XX_DIO_INPUT
#undef  TM16XX_DELAY

#define  TM16XX_STB_H        TM1668_STB_H
#define  TM16XX_STB_L        TM1668_STB_L
#define  TM16XX_CLK_H        TM1668_CLK_H
#define  TM16XX_CLK_L        TM1668_CLK_L
#define  TM16XX_DIO_H        TM1668_DIO_H
#define  TM16XX_DIO_L        TM1668_DIO_L
#define  TM16XX_DIO_STATUS    TM1668_DIO_STATUS
#define  TM16XX_DIO_OUTPUT    tm1668_dio_output()
#define  TM16XX_DIO_INPUT     tm1668_dio_input()
#define  TM16XX_DELAY         tm1668_delay_1us()

uint8_t tm1668_readbyte(void)         //读数据1个字节
{
    uint8_t byte = 0;
    TM16XX_READ_BYTE(byte);
    return byte;
}

void tm1668_writebyte(uint8_t byte)         //写数据1个字节
{
    TM16XX_WRITE_BYTE(byte);
}

void tm1668_writecmd(uint8_t cmd)               //写命令
{
    TM16XX_STB_H;
    TM16XX_CLK_H;
    TM16XX_DIO_H; //通讯开始前通讯端口全部初始化为“1”
    tm1668_delay(30);
    TM16XX_WRITE_BYTE(cmd);
}

void tm1668_readkey(uint8_t *pbuffer, uint8_t len)           //16个显存依次显示出来
{
    uint8_t index;
    tm1668_writecmd(0x42); //送读按键命令（42H）
    TM16XX_DIO_H;
    TM16XX_DIO_INPUT;
    if(len > 5)
    {
        len = 5;
    }
    for(index = 0;index < len;index++)
    {
        pbuffer[index] = tm1668_readbyte();
    }
    TM16XX_DIO_OUTPUT;
    TM16XX_STB_H;
    TM16XX_DIO_H;
}

void tm1668_display(uint8_t addr,const uint8_t *pbuffer,uint8_t len)
{
    uint8_t index;
    if( (len > 0) && ( addr < 16) )
    {
        tm1668_writecmd(0x00 | 0x00); //模式 4x13  5x12  6x11  7x10
        tm1668_writecmd(0x40 | 0x00); //写数据到显示寄存器的方式采用地址自动加一
        tm1668_writecmd(0x80 | 0x08); //开显示，0x80最小 0x8F最大亮度
        tm1668_writecmd(0xc0 | (0x0F&addr) ); //设置显示地址命令：从00H开
        if((len +addr) > 16)
        {
            len = 16 - addr;
        }
        for(index = 0;index < len ;index++)
        {
            tm1668_writebyte(pbuffer[index]);
        }
    }
    TM16XX_STB_H;
    TM16XX_DIO_H;
}

void tm1668_display_cleanall(void)
{
    uint8_t index;
    tm1668_writecmd(0xc0); //设置显示地址命令：从00H开
    for(index = 0;index < 16 ;index++)
    {
        tm1668_writebyte(0x00);
    }
    TM16XX_STB_H;
    TM16XX_DIO_H;
}

void tm1668_display_off(void)
{
    tm1668_writecmd(0x80); //关显示
    TM16XX_STB_H;
    TM16XX_DIO_H;
}

void tm1668_display_on(void)
{
    tm1668_writecmd(0x00 | 0x00); //模式 4x13  5x12  6x11  7x10
    tm1668_writecmd(0x40 | 0x00); //写数据到显示寄存器的方式采用地址自动加一
    tm1668_writecmd(0x80 | 0x08); //开显示，0x80最小 0x8F最大亮度
    tm1668_writecmd(0xc0 | 0x00); //设置显示地址命令：从00H开
    TM16XX_STB_H;
    TM16XX_DIO_H;
}

int drv_tm1668_init(void)
{
    tm1668_gpio_init();
    tm1668_display_on();
    tm1668_display_cleanall();

    return 0;
}


